package com.bizframework.springhb.support.serialization.xstream.converter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

import org.hibernate.collection.PersistentBag;
import org.hibernate.collection.PersistentList;
import org.hibernate.collection.PersistentMap;
import org.hibernate.collection.PersistentSet;
import org.hibernate.collection.PersistentSortedMap;
import org.hibernate.collection.PersistentSortedSet;
import org.hibernate.proxy.HibernateProxy;

import com.thoughtworks.xstream.mapper.Mapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;

public class HibernateMapper extends MapperWrapper {

	@SuppressWarnings("rawtypes")
	Map collectionMap = new HashMap();

	@SuppressWarnings("unchecked")
	public void init() {
		collectionMap.put(PersistentBag.class, ArrayList.class);
		collectionMap.put(PersistentList.class, ArrayList.class);
		collectionMap.put(PersistentMap.class, HashMap.class);
		collectionMap.put(PersistentSet.class, HashSet.class);
		collectionMap.put(PersistentSortedMap.class, TreeMap.class);
		collectionMap.put(PersistentSortedSet.class, TreeSet.class);
	}

	public HibernateMapper(Mapper arg0) {
		super(arg0);
		init();
	}

	@SuppressWarnings("rawtypes")
	public Class defaultImplementationOf(Class clazz) {
		// System.err.println("checking class:" + clazz);
		if (collectionMap.containsKey(clazz)) {
			return (Class) collectionMap.get(clazz);
		}

		return super.defaultImplementationOf(clazz);
	}

	public String serializedClass(@SuppressWarnings("rawtypes") Class clazz) {
		// check whether we are hibernate proxy and substitute real name
		for (int i = 0; i < clazz.getInterfaces().length; i++) {
			if (HibernateProxy.class.equals(clazz.getInterfaces()[i])) {
				return clazz.getSuperclass().getName();
			}
		}
		if (collectionMap.containsKey(clazz)) {
			return ((Class<?>) collectionMap.get(clazz)).getName();
		}

		return super.serializedClass(clazz);
	}

}